package com.zeny.coding.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zeny.coding.constants.CourseConstants;
import com.zeny.coding.dto.FileDto;
import com.zeny.coding.dto.PageDto;
import com.zeny.coding.entity.File;
import com.zeny.coding.entity.FileExample;
import com.zeny.coding.mapper.FileMapper;
import com.zeny.coding.service.FileService;
import com.zeny.coding.util.SnowFlake;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <h2>文件服务</h2>
 *
 * @Author Zeny
 */
@SuppressWarnings("all")
@Service
public class FileServiceImpl implements FileService {

    @Autowired
    private FileMapper fileMapper;

    @Override
    public void list(PageDto<FileDto> pageDto) {
        //分页
        PageHelper.startPage(pageDto.getPage(), pageDto.getSize());
        //设置条件
        FileExample fileExample = new FileExample();
        fileExample.setOrderByClause("id desc");
        //查询结果
        List<File> fileList = this.fileMapper.selectByExample(fileExample);
        PageInfo<File> pageInfo = new PageInfo<>(fileList);
        //设置总条数
        pageDto.setTotal(pageInfo.getTotal());
        //封装成DTO传输
        List<FileDto> fileDtoList = new ArrayList<>();
        for (File file : fileList) {
            FileDto fileDto = new FileDto();
            BeanUtils.copyProperties(file, fileDto);
            fileDtoList.add(fileDto);
        }
        //设置记录数
        pageDto.setList(fileDtoList);
    }

    @Override
    public void save(FileDto fileDto) {
        //DTO转~
        File file = new File();
        BeanUtils.copyProperties(fileDto, file);
        //根据文件标识key查找文件记录
        File fileDB = selectByKey(file.getKey());
        if (fileDB == null) {
            //第一次上传
            //算法算法生成ID
            SnowFlake snowFlake = new SnowFlake(
                    CourseConstants.dataCenterId,
                    CourseConstants.machineId);
            file.setId(String.valueOf(snowFlake.nextId()));
            file.setCreatedAt(new Date());
            file.setUpdatedAt(file.getCreatedAt());
            this.fileMapper.insertSelective(file);
        } else {
            //更新分片索引
            fileDB.setShardIndex(fileDto.getShardIndex());
            fileDB.setPath(fileDto.getPath());
            fileDB.setUpdatedAt(new Date());
            this.fileMapper.updateByPrimaryKeySelective(fileDB);
        }
    }



    @Override
    public FileDto findById(String id) {
        File file = this.fileMapper.selectByPrimaryKey(id);
        FileDto fileDto = new FileDto();
        BeanUtils.copyProperties(file, fileDto);
        return fileDto;
    }

    @Override
    public void deleteById(String id) {
        this.fileMapper.deleteByPrimaryKey(id);
    }


    @Override
    public FileDto findByKey(String key) {
        File fileDB = selectByKey(key);
        if (fileDB == null) {
            return null;
        }
        FileDto fileDto = new FileDto();
        BeanUtils.copyProperties(fileDB, fileDto);
        return fileDto;
    }

    @Transactional
    @Override
    public void delete(FileDto fileDto, String path) {
        //文件的相对路径
        String relativePath = fileDto.getPath();
        //文件的绝对路径
        String absolutePath = path + relativePath;
        java.io.File localFile = new java.io.File(absolutePath);
        localFile.delete();
        this.fileMapper.deleteByPrimaryKey(fileDto.getId());
    }

    /**
     * <h2>根据文件标识key查找文件保存记录</h2>
     * @param key
     **/
    public File selectByKey(String key) {
        FileExample example = new FileExample();
        example.createCriteria().andKeyEqualTo(key);
        List<File> fileList = this.fileMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(fileList)) {
            return null;
        } else {
            return fileList.get(0);
        }
    }
}
